home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 2 / Gold Medal Software Volume 2 (Gold Medal) (1994).iso / prog / asm_0_m.arj / KEYMOD.ASM < prev    next >
Assembly Source File  |  1986-03-01  |  10KB  |  401 lines

  1. cseg    segment para public 'code'
  2. org    100h
  3. keymod    proc far
  4.  
  5. keyaddr equ 9h*4    ; keyboard interrupt address
  6. vidaddr equ 10h*4    ; video interrupt address
  7. usraddr equ 61h*4    ; user interrupt address
  8. whozat    equ 1235h    ; signature value
  9.  
  10. ; Memory-resident program to intercept keyboard interrupts.
  11. ; Once loaded, this program will remain resident until DOS is reloaded.
  12. ; The program can be re-run, to change the original options.
  13. ; This program is used to control the state of the following keys:
  14. ;
  15. ;    Caps Lock  : U+ (force on), U- (force off), or U (normal)
  16. ;    Num Lock   : N+ (force on), N- (force off), or N (normal)
  17. ;    Alt Key    : A+ (force on), A- (force off), or A (normal)
  18. ;    Ctrl Key   : C+ (force on), C- (force off), or C (normal)
  19. ;    Left Shift : L+ (force on), L- (force off), or L (normal)
  20. ;    Right Shift: R+ (force on), R- (force off), or R (normal)
  21. ;    Boot       : B+ or B (on - normal) or B- (off - disabled)
  22. ;    Ctrl-Break : X+ or X (on - normal) or X- (off - disabled)
  23. ;    Suspend    : S+ (enable pause), S- or S (normal - no effect)
  24. ;    Reset all keys to normal: *
  25. ;
  26. ; For example, 'KEYMOD U+ B- X-' would force caps lock on, disable booting via
  27. ; Alt-Ctrl-Del, and disable Ctrl-Break.
  28.  
  29.     assume cs:cseg,ds:cseg,ss:nothing,es:nothing
  30.     jmp p100        ; start-up code
  31.  
  32. keyint    dd 0            ; keyboard interrupt vector
  33. vidint    dd 0            ; video interrupt vector
  34. signature dw whozat        ; program's signature
  35.  
  36.                 ; keyboard mod table
  37.                 ; 0 = no change, 1 = force off, 2 = force on
  38. modtbl    db 0ffh         ; insert - not used
  39.     db 0            ; caps lock
  40.     db 0            ; num lock
  41.     db 0ffh         ; suspend - used below
  42.     db 0            ; alt
  43.     db 0            ; ctrl
  44.     db 0            ; left shift
  45.     db 0            ; right shift
  46. noboot    db 0            ; disable boot if 1
  47. nobreak db 0            ; disable ctrl-break if 1
  48. suspend db 0            ; enable suspend key if 2
  49. tstack    db 16 dup ('stack   ')  ; temporary stack
  50. estack    db 0            ; end of temp stack
  51. holdss    dw 0            ; original ss
  52. holdsp    dw 0            ; original sp
  53.  
  54. p000:    sti            ; interrupt (resident) code starts here
  55.     push ax         ; save registers
  56.     push cx
  57.     push es
  58.     push di
  59.     pushf
  60.  
  61.     mov ax,40h
  62.     mov es,ax
  63.     mov di,17h        ; point to keyboard flag
  64.     mov ah,es:[di]        ; keyboard state - flag in ah
  65.  
  66.     mov cx,8
  67.     mov di,offset modtbl    ; point to mod table
  68. p010:    mov al,cs:[di]        ; get mod value
  69.     cmp al,1        ; turn key off?
  70.     jz p020         ; yes
  71.     cmp al,2        ; turn key on?
  72.     jz p015         ; yes
  73.     jmp p030        ; do nothing with this one
  74.  
  75. p015:    mov al,1        ; turn key on
  76.     rol al,cl        ; rotate left
  77.     ror al,1        ; back 1
  78.     or ah,al        ; switch bits on in ah
  79.     jmp p030
  80.  
  81. p020:    mov al,1        ; turn key off
  82.     rol al,cl
  83.     ror al,1
  84.     xor al,0ffh        ; flip the bits
  85.     and ah,al        ; switch bits off in ah
  86.  
  87. p030:    inc di
  88.     loop p010        ; continue
  89.  
  90.     mov al,cs:[noboot]    ; is boot disabled?
  91.     cmp al,1
  92.     jnz p040        ; no
  93.     test ah,08h        ; alt pressed?
  94.     jz p040         ; no
  95.     test ah,04h        ; ctrl pressed?
  96.     jz p040         ; no
  97.     and ah,0fbh        ; tried alt-ctrl-del, turn off ctrl!
  98.  
  99. p040:    test ah,04h        ; is ctrl pressed?
  100.     jz p050         ; no
  101.     mov al,cs:[nobreak]    ; is ctrl-break disabled?
  102.     cmp al,1
  103.     jnz p050        ; no
  104.     in al,60h        ; get next char from kybd
  105.     cmp al,46        ; is it a 'c'?
  106.     jz p045         ; yes
  107.     cmp al,70        ; is it a break?
  108.     jz p045         ; yes
  109.     jmp p050
  110. p045:    and ah,0fbh        ; turn off ctrl!
  111.  
  112. p050:    mov di,17h
  113.     mov es:[di],ah
  114.     popf
  115.     pop di
  116.     pop es
  117.     pop cx
  118.     pop ax
  119.     jmp cs:[keyint]
  120.  
  121. p060:    sti            ; resident code for video interrupt
  122.     push ax         ; save registers
  123.     push di
  124.     push es
  125.  
  126.     mov al,cs:[suspend]    ; is suspend on?
  127.     cmp al,2
  128.     jnz p070        ; no
  129.     mov di,40h
  130.     mov es,di
  131.     mov di,17h        ; point to keyboard flag
  132.     mov al,es:[di]        ; get keyboard flag
  133.     test al,10h        ; check suspend
  134.     jz p070         ; it's off
  135.     cmp ah,7        ; scroll down?
  136.     jz p065         ; yes
  137.     cmp ah,6        ; scroll up?
  138.     jnz p070        ; no
  139.  
  140. p065:
  141.     cli            ; no interrupts
  142.     mov ax,ss        ; save original stack
  143.     mov cs:[holdss],ax
  144.     mov cs:[holdsp],sp
  145.     mov ax,cs        ; point to temp stack
  146.     mov ss,ax        ; make ss=cs
  147.     mov sp,offset estack
  148.     sti            ; allow interrupts
  149.  
  150.     mov ah,0        ; wait for a key to be pressed
  151.     int 16h
  152.  
  153.     cli            ; no interrupts
  154.     mov ax,cs:[holdss]    ; restore original stack
  155.     mov ss,ax
  156.     mov sp,cs:[holdsp]
  157.     sti            ; allow interrupts
  158.  
  159.     mov di,17h
  160.     mov al,es:[di]        ; keyboard state - flag in al
  161.     and al,0efh        ; turn suspend off
  162.     mov es:[di],al        ; re-set state
  163.  
  164. p070:    pop es
  165.     pop di
  166.     pop ax
  167.     jmp cs:[vidint]     ; jump to video interrupt
  168.  
  169.  
  170. p100:                ; transient code starts here
  171.     call p120        ; get current keyboard vector
  172.     call p140        ; decode command line
  173.     call p160        ; turn suspend off
  174.     call p180        ; display key settings
  175.     mov al,firstime
  176.     cmp al,1        ; first time?
  177.     jz p105         ; yes - leave resident
  178.     int 20h         ; no - vanish!
  179.  
  180. p105:    mov dx,offset p100    ; last byte of resident portion
  181.     int 27h         ; terminate
  182.  
  183. p120    proc near        ; get current keyboard buffer
  184.     mov dx,offset copyr
  185.     call p200        ; display copyright
  186.     mov di,usraddr+2    ; point to user interrupt
  187.     mov ax,0
  188.     mov es,ax
  189.     mov bx,es:[di]        ; get current contents
  190.     mov es,bx        ; make it the segment
  191.     mov di,offset signature
  192.     mov cx,es:[di]        ; get signature
  193.     cmp cx,whozat        ; is it this program?
  194.     jz p125         ; yes - don't install it
  195.  
  196.     mov ax,0
  197.     mov es,ax
  198.     mov di,keyaddr        ; point to keyboard interrupt
  199.     mov ax,es:[di]        ; get current ip
  200.     mov bx,es:[di+2]    ; get current cs
  201.     mov si,offset keyint    ; save address
  202.     mov [si],ax
  203.     mov [si+2],bx
  204.  
  205.     mov di,vidaddr        ; point to video interrupt
  206.     mov ax,es:[di]        ; get current ip
  207.     mov bx,es:[di+2]    ; get current cs
  208.     mov si,offset vidint    ; save address
  209.     mov [si],ax
  210.     mov [si+2],bx
  211.  
  212.     mov al,1        ; first time through
  213.     mov firstime,al     ; set first time flag
  214.     mov dx,offset install
  215.     call p200
  216.     mov ax,0
  217.     mov es,ax
  218.     mov bx,ds
  219.     cli            ; no interrupts
  220.  
  221.     mov di,keyaddr
  222.     mov ax,offset p000
  223.     mov es:[di],ax        ; change keyboard interrupt
  224.     mov es:[di+2],bx
  225.  
  226.     mov di,vidaddr
  227.     mov ax,offset p060
  228.     mov es:[di],ax        ; change video interrupt
  229.     mov es:[di+2],bx
  230.  
  231.     mov di,usraddr        ; set user interrupt - segment only
  232.     mov ax,offset signature
  233.     mov es:[di],ax
  234.     mov es:[di+2],bx
  235.  
  236.     sti            ; allow interrupts again
  237.  
  238.     push cs
  239.     pop bx            ; get current cs
  240.  
  241. p125:    mov si,offset realcs
  242.     mov [si],bx        ; save real cs
  243.     ret
  244. p120    endp
  245.  
  246. p140    proc near        ; decode command line
  247.     mov si,80h        ; point to command line
  248.     mov ch,0
  249.     mov cl,[si]        ; get length
  250.     jcxz p159        ; length is zero
  251.     push cx         ; save length
  252.     inc si            ; point to first char
  253.     push si         ; save start addr
  254. p142:    mov al,[si]        ; get character
  255.     cmp al,'a'              ; lower case?
  256.     jb p144         ; no
  257.     cmp al,'z'              ; lower case?
  258.     ja p144         ; no
  259.     sub al,'a'-'A'          ; yes - make it upper case
  260.     mov [si],al        ; put it back on the line
  261.  
  262. p144:    inc si            ; point to next
  263.     loop p142        ; all done?
  264.  
  265.     mov ax,realcs
  266.     mov es,ax
  267.     pop bx            ; get start addr
  268.     pop cx            ; get command line length
  269.  
  270. p146:    mov al,[bx]        ; get character
  271.     cmp al,' '              ; is it a space?
  272.     jz p155         ; yes
  273.     cmp al,'*'              ; is it an asterisk?
  274.     jz p146a        ; yes
  275.     cmp al,'8'              ; is it an 8 (lower-case asterisk)?
  276.     jz p146a        ; yes
  277.     jmp p146b
  278.  
  279. p146a:    mov di,offset modtbl    ; clear all key modifications
  280.     mov cx,11
  281.     mov al,0
  282.     rep stosb        ; clear mod table
  283.     jmp p159        ; return
  284.  
  285. p146b:    mov si,offset tokens    ; search token list
  286.     mov dl,0        ; number of items to compare
  287. p147:    mov dh,[si]        ; get token
  288.     cmp dh,al        ; same?
  289.     jz p148         ; yes
  290.     inc si            ; point to next token
  291.     inc dl
  292.     cmp dl,11        ; done?
  293.     jnz p147        ; no
  294.     jmp p155        ; no hit
  295.  
  296. p148:                ; got a valid character
  297.     mov dh,0
  298.     mov di,offset modtbl
  299.     add di,dx        ; got offset into table
  300.     mov es:[di],dh        ; clear current setting
  301.     mov dh,[bx+1]        ; get next character
  302.     cmp dh,'+'              ; is it a plus?
  303.     jnz p149        ; no
  304.     mov dh,2        ; set it on
  305.     jmp p150
  306. p149:    cmp dh,'-'              ; is it a minus?
  307.     jnz p155        ; no
  308.     mov dh,1        ; set it off
  309. p150:    mov es:[di],dh        ; change mod table
  310.  
  311. p155:    inc bx            ; point to next char
  312.     loop p146        ; done?
  313.  
  314. p159:    ret
  315. p140    endp
  316.  
  317. p160    proc near        ; turn suspend off
  318.     push ax
  319.     push es
  320.     push di
  321.     mov ax,40h
  322.     mov es,ax
  323.     mov di,17h        ; point to keyboard flag
  324.     mov al,es:[di]        ; keyboard state - flag in al
  325.     and al,0efh        ; turn suspend off
  326.     mov es:[di],al        ; re-set state
  327.     pop di
  328.     pop es
  329.     pop ax
  330.     ret
  331. p160    endp
  332.  
  333. p180    proc near        ; display status of keys
  334.     mov ax,realcs        ; get real code segment
  335.     mov es,ax        ; get code seg in es
  336.     mov cx,11        ; items to display
  337.     mov di,offset modtbl    ; point to mod table
  338.     mov dx,offset dummy1    ; point to first message
  339.  
  340. p181:
  341.     mov si,dx
  342.     mov al,[si]        ; get first char of message
  343.     cmp al,255        ; no show?
  344.     jz p185         ; yes
  345.     call p200        ; print key name(s)
  346.     push dx
  347.     mov al,es:[di]
  348.     cmp al,0
  349.     jb p182         ; out of range
  350.     cmp al,2
  351.     jbe p183
  352. p182:    mov al,2
  353. p183:    push cx
  354.     mov cl,4
  355.     mov ah,0
  356.     rol al,cl        ; convert number to message offset
  357.     pop cx
  358.     mov dx,offset statemsg
  359.     add dx,ax
  360.     call p200        ; print status message
  361.     pop dx            ; get part 1 address
  362. p185:    add dx,18        ; point to next one
  363.     inc di            ; point to next status byte
  364.     loop p181        ; go back for more...
  365.     ret
  366. p180    endp
  367.  
  368. p200    proc near        ; display message
  369.     push ax
  370.     mov ah,9
  371.     int 21h
  372.     pop ax
  373.     ret
  374. p200    endp
  375.  
  376. dummy1    db 255,'                $'      ; key names
  377. capsmsg db 'Caps Lock    (U):$'
  378. numlmsg db 'Num Lock     (N):$'
  379. dummy2    db 255,'                $'
  380. altkmsg db 'Alt key      (A):$'
  381. ctrlmsg db 'Ctrl key     (C):$'
  382. lshkmsg db 'Left shift   (L):$'
  383. rshkmsg db 'Right shift  (R):$'
  384. bootmsg db 'Alt-Ctrl-Del (B):$'
  385. cbrkmsg db 'Ctrl-Break   (X):$'
  386. suspmsg db 'Suspend      (S):$'
  387.  
  388. statemsg db ' Not affected',10,13,'$'   ; status messages
  389.      db ' Off         ',10,13,'$'
  390.      db ' On          ',10,13,'$'
  391.  
  392. copyr    db 'KEYMOD - Copyright 1983 Data Base Decisions',10,13,10,13,'$'
  393. install db 'Installing keyboard modifier',10,13,10,13,'$'
  394. realcs    dw 0            ; cs of first copy of this program
  395. firstime db 0            ; 0 if repeat, 1 if first time (original)
  396. tokens    db 255,'UN',255,'ACLRBXS'; commands
  397.  
  398. keymod    endp
  399. cseg    ends
  400. end    keymod
  401.